#pragma once

#include "MODELOBJDef.h"
#include "CGALDefinition.h"
#include "MorphologicalProc.h"

#ifdef MYLIB_API_EXPORT
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif


class MYLIB_API CompGraph
{
protected:
	static std::auto_ptr<CompGraph> _instance;

public:
	//definition of graph
	typedef std::pair<Nef_polyhedron_3*, Nef_polyhedron_3*> Edge;
	typedef std::vector<Nef_polyhedron_3*> NodeList;
	typedef std::vector<Edge*> EdgeList;
	EdgeList el;
public:
	//
	CompGraph(){}
	~CompGraph()
	{
		EdgeList::iterator el_itr = el.begin();
		while(el_itr != el.end())
		{
			Edge* e = *el_itr++;
			if (e != NULL)
			{
				delete e;//test whether the pair is destroyed
				e = NULL;
			}
		}
		el.clear();
	}

	static CompGraph* GetSingleton()
	{
		if (NULL == _instance.get())
		{
			_instance.reset(new CompGraph);
		}
		return _instance.get();
	}

public:
	//build a CompGraph from a MODLEOBJ
	//obj:model
	//bFlag:(1 closing 0 expansion other no process)
	//size:scale
	//tol:tolarance for detecting collision
	void build_graph(ModelOBJ* obj,float size, int bFlag, float tol);
	
	//combine polyhedron based on CompGraph
	//return true combined false not combined
	bool combine_polys();
	
	//visualization of graph
	//void visualize(std::string path);
	
private:
	//add an edge to the EdgeList
	void add_edge(Edge* e);
	
	//delete an edge from the EdgeList
	bool del_edge(Edge* e);
	
	//sum the Nef_polyhedrons of an edge and update Nef_polyhedron
	//return false single node true combined
	bool handle_edge(Edge* e);
	
	//collision detection of two solids true for collision with tol
	bool detect_collision(Nef_polyhedron_3* poly1, Nef_polyhedron_3* poly2);
	
};
